#include "VideoSubFinder.h"
#include "DataTypes.h"
#include "OCVVideoLoader.h"
#include "OCVVideo.h"
#include "SSAlgorithms.h"
#include <iostream>
#include <thread>
#include <vector>
//查找image轮廓
//src=源图像
//ret_rects=返回找到轮廓矩形数组
//ocr_threshold=二值化处理系数[0-1]区间取灰度0-255
cv::Mat preprocessImage(cv::Mat src,double ocr_threshold=0.8,bool type=true){
	cv::Mat sobel, gray, binary, dilate1, dilate2, erode1,dst;

    //转灰度
    cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
	//sobel算子
	cv::Sobel(gray,sobel,CV_8U,1,0,3);
	if (ocr_threshold>1) { ocr_threshold=1.0; }
	//二值化处理
	if (type) {
		cv::threshold(sobel, binary, int(255*ocr_threshold), 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
    }else{
		cv::threshold(sobel, binary, 0 ,int(255*ocr_threshold), cv::THRESH_BINARY | cv::THRESH_OTSU);
	}
    cv::Mat k1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(30,9));
    cv::Mat k2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(24,4));
	cv::dilate(binary,dilate1,k2);
	cv::erode(dilate1,erode1,k1);
	cv::dilate(erode1,dilate2,k2);
    // 形态学处理(可选)
    //cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3));
    //cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, kernel);
	//cv::imwrite(std::string("/home/knife/test_binary.jpg"),binary);
	return dilate2;
}
std::vector<cv::RotatedRect> findTextRegion(cv::Mat img){
	std::vector<cv::RotatedRect> ret_rects;
	cv::Mat approx;
    // 查找轮廓
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    //cv::findContours(img, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
    cv::findContours(img, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE,cv::Point(0,0));
    // 3. 绘制轮廓和矩形标记
    for(size_t i = 0; i < contours.size(); i++) {
    cv::drawContours(img, contours, i, cv::Scalar(0, 255, 0), 1);
		
		double area=cv::contourArea(contours[i]);
		
		if (area < 250) { continue; }
		
		double epsilon=0.001*arcLength(contours[i],true);
		
		cv::approxPolyDP(contours[i],approx,epsilon,true);

		cv::RotatedRect rect=minAreaRect(contours[i]);
		
		int m_width=rect.boundingRect().width;
		int m_height=rect.boundingRect().height;
		
		if (m_height>m_width*1.2) { continue; }


		ret_rects.push_back(rect);
		// 可选: 显示矩形坐标信息
	}
	
	return ret_rects;
}


//根据轮廓矩形在原图画矩形框
cv::Mat drawRect(cv::Mat dst,std::vector<cv::RotatedRect> rects){
	cv::Mat ret_dst;
	ret_dst=dst.clone();
	for (cv::RotatedRect rect : rects){
		cv::Point2f P[4];
		rect.points(P);
		for (int i=0;i<=3;i++){
			cv::line(ret_dst,P[i],P[(i+1)%4],cv::Scalar(0,255,0),2);
		}
	}
	return ret_dst;
}
bool GetImage(cv::Mat src,cv::Mat& dst,cv::Rect rec){
    if (!src.empty())
    {
		if (rec.x > src.cols)
		{
			printf("rec.x Exceeding image size!");
			return false;
		}
		if (rec.y > src.rows)
		{
			printf("rec.y Exceeding image size!");
			return false;
		}
		if ((rec.x + rec.width) > src.cols){
			rec.width=src.cols-rec.x;
		}
		if ((rec.y + rec.height) > src.rows){
			rec.height=src.rows-rec.y;
		}
		dst=src(rec);
		return true;
	}else{
		return false;
		
	}
}
int main(){
	//初始化
	OCVVideo* p_cv=new OCVVideo();
	std::vector<cv::RotatedRect> rects;
	cv::Mat rec_image,find_image,find2_image,draw_image;
	double max_time=p_cv->m_frameNumbers/p_cv->m_fps;
	double start_time=28.0;
	double end_time=40.0;
	//cv::Rect rec(350,600,600,70);
	//double start_time=0;
	//double end_time=max_time;
	cv::Rect rec(500,900,920,70);

	//打开视频文件
	p_cv->OpenMovie(wxT("/home/knife/test.mp4"),NULL,0);
	//输出视频基本参数
	printf("width:%ld height:%ld fps:%f frameNumbers:%f\n",p_cv->m_Width,p_cv->m_Height,p_cv->m_fps,p_cv->m_frameNumbers);
	//输出视频首帧
	//cv::imwrite("/home/knife/test/test.jpg",p_cv->m_cur_frame);
	p_cv->SetNullRender();
	if (start_time>max_time) { start_time=0.0; }
	if (end_time>max_time) { end_time=max_time; }
	//开始逐秒遍历视频
 	for (double i=start_time;i<end_time;i++){
	//double i=186.00;
		//转换秒时间
		int hh,mm,ss,tmp;
		hh=(int)i / 3600;
		tmp=((int)i) % 3600;
		mm=tmp / 60;
		ss=tmp % 60;
		p_cv->SetPos(i);
		//获取指定矩形图像
		if (GetImage(p_cv->m_cur_frame,rec_image,rec)){
			//将指定矩形图复制到待处理rec_image
			//cv::imwrite(std::string("/home/knife/test/test_")+std::to_string((int)i)+std::string(".jpg"),rec_image);
			//对rec_image标记轮廓find_image并获取矩形数据到f_rects
			find_image=preprocessImage(rec_image,0.6,true);
			rects=findTextRegion(find_image);
			cv::imwrite(std::string("/home/knife/test/test_find_")+std::to_string((int)i)+std::string(".jpg"),find_image);
			printf("[%2d:%2d:%2d] rects.size=%ld",hh,mm,ss,rects.size());
			if (rects.size()>0){
				//在源图画出矩形框
				//以下，可以输出图像，也可以改成OCR识别操作
				draw_image=drawRect(rec_image,rects);
				cv::imwrite(std::string("/home/knife/test/test_")+std::to_string((int)i)+std::string(".jpg"),draw_image);
			}
		}

	}

 
 
	p_cv->CloseMovie();
	
	return 0;
}
